package com.yourenbang.lingyun.transaction.web.service.impl.migrate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.redis.RedisUtils;
import com.yourenbang.lingyun.domain.PayTransactionIndex;
import com.yourenbang.lingyun.domain.PayTransactionIndexExample;
import com.yourenbang.lingyun.mapper.PayTransactionIndexMapper;
import com.yourenbang.lingyun.mapper.UserBaseExtMapper;
import com.yourenbang.lingyun.transaction.config.AcmTransactionParams;
import com.yourenbang.lingyun.transaction.mapper.TransactionPayTransactionMapper;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.MigrateDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.QueryTableDateDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.QueryTablePageDTO;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.KlksPayTransactionIndex;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.KlksPayTransactionPO;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.PayWithdrawalPO;
import com.yourenbang.lingyun.transaction.web.service.migrate.PayTransactionBatchMigrateService;
import com.yourenbang.lingyun.transaction.web.service.migrate.PayTransactionMigrateService;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class PayTransactionBatchMigrateServiceImpl extends AbstractMigrateService implements PayTransactionBatchMigrateService {

    @Autowired
    private RedisUtils redis;
    @Autowired
    private AcmTransactionParams acmTransactionParams;
    @Autowired
    private UserBaseExtMapper userBaseExtMapper;
    @Autowired
    private CommonMigrateServiceImpl commonMigrateService;
    @Autowired
    private TransactionPayTransactionMapper transactionPayTransactionMapper;
    @Autowired
    private PayTransactionIndexMapper payTransactionIndexMapper;
    @Autowired
    private PayTransactionMigrateService payTransactionMigrateService;


    @Override
    public boolean migratePayTransactionPage(QueryTablePageDTO dto) {

        String uri = "/query/pay/base/query/limit";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<KlksPayTransactionPO> klksPayTransactionPOList = jsonArray.toJavaList(KlksPayTransactionPO.class);

        savePayTransaction(klksPayTransactionPOList);
        return true;
    }

    /**
     * 批量插入交易
     *
     * @param klksPayTransactionPOList
     */
    private void savePayTransaction(List<KlksPayTransactionPO> klksPayTransactionPOList) {

        Map<Integer, List<PayTransaction>> posMap = new HashMap<>();
        for (KlksPayTransactionPO klksPayTransactionPO : klksPayTransactionPOList) {
            try {
                if (StringUtils.equals(klksPayTransactionPO.getProductType(),"06")){
                    KLog.warn("充值交易不迁移");
                    continue;
                }

                if (!Objects.isNull(klksPayTransactionPO.getTransAmt())){
                    if (klksPayTransactionPO.getTransAmt().compareTo(new BigDecimal("99999999.00")) > 0){
                        continue;
                    }
                }

                String userBaseId = getUserBaseId(userBaseExtMapper, klksPayTransactionPO.getUserId(), redis);
                PayTransaction payTransaction = payTransactionMigrateService.fmtPayTransactionData(klksPayTransactionPO,
                        userBaseId);

                int index = getTransTableIndex(userBaseId);
                List<PayTransaction> payTransactions = posMap.get(index);
                if (payTransactions == null) {
                    payTransactions = new ArrayList<>();
                }
                payTransactions.add(payTransaction);
                posMap.put(index, payTransactions);
            } catch (Exception e) {
                KLog.error("迁移交易失败,交易记录:{}", klksPayTransactionPO, e);
            }
        }
        for (Map.Entry<Integer, List<PayTransaction>> entry : posMap.entrySet()) {
            int size = entry.getValue().size();
            if (size != 0) {
                KLog.info("[订单迁移]准备插入新表数:{}", size);
                int i = transactionPayTransactionMapper.batchInsert(entry.getKey(), entry.getValue());
                KLog.info("[订单迁移]插入新表成功数:{}", i);
            }

        }
    }

    @Override
    public boolean migratePayTransactionOrder(QueryTableDateDTO dto) {
        String uri = "/query/pay/base/query/order";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<KlksPayTransactionPO> klksPayTransactionPOList = jsonArray.toJavaList(KlksPayTransactionPO.class);

        updatePayTransaction(klksPayTransactionPOList);
        return true;
    }

    @Override
    public boolean migratePayTransactionIndexPage(QueryTablePageDTO dto) {

        String uri = "/query/pay/base/query/limit";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<KlksPayTransactionIndex> klksPayTransactionIndexList = jsonArray.toJavaList(KlksPayTransactionIndex.class);

        savePayTransactionIndex(klksPayTransactionIndexList);
        return true;
    }

    private void savePayTransactionIndex(List<KlksPayTransactionIndex> klksPayTransactionIndexList) {
        List<PayTransactionIndex> payTransactionIndexList = new ArrayList<>();
        for (KlksPayTransactionIndex klksPayTransactionIndex : klksPayTransactionIndexList) {
            try {
                if (klksPayTransactionIndex.getTransAmt().compareTo(new BigDecimal("99999999"))==1){
                    KLog.error("迁移交易index表失败,金额过大,index记录:{}", klksPayTransactionIndex);
                }
                String userBaseId = getUserBaseId(userBaseExtMapper, klksPayTransactionIndex.getUserId(), redis);
                PayTransactionIndex payTransactionIndex = payTransactionMigrateService.fmtPayTransactionIndexData(klksPayTransactionIndex, userBaseId);
                payTransactionIndexList.add(payTransactionIndex);
            } catch (Exception e) {
                KLog.error("迁移交易index表失败,index记录:{}", klksPayTransactionIndex, e);
            }
        }
        if (payTransactionIndexList.size() != 0) {
            int i = payTransactionIndexMapper.batchInsert(payTransactionIndexList);
            KLog.info("共[{}]条,更新[{}]条index记录结束", payTransactionIndexList.size(), i);
        }
    }

    @Override
    public boolean migratePayTransactionIndexOrder(QueryTableDateDTO dto) {
        String uri = "/query/pay/base/query/order";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<KlksPayTransactionIndex> klksPayTransactionIndexList = jsonArray.toJavaList(KlksPayTransactionIndex.class);

        updatePayTransactionIndex(klksPayTransactionIndexList);
        return true;
    }

    @Override
    public boolean migratePayWithdrawPage(QueryTablePageDTO dto) {
        String uri = "/query/pay/base/query/limit";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<PayWithdrawalPO> klksPayWithdrawalList = jsonArray.toJavaList(PayWithdrawalPO.class);

        updatePayWithdraw(klksPayWithdrawalList);
        return true;
    }

    private void updatePayWithdraw(List<PayWithdrawalPO> klksPayWithdrawalList) {
        for (PayWithdrawalPO payWithdrawalPO : klksPayWithdrawalList) {
            try {

                MigrateDTO migrateDTO = new MigrateDTO();
                migrateDTO.setOpt(MigrateDTO.OPT_UPDATE);
                migrateDTO.setData(payWithdrawalPO.toJSON());

                payTransactionMigrateService.payWithdrawal(migrateDTO);
            } catch (Exception e) {
                KLog.error("更新提款记录失败,数据:{}", payWithdrawalPO, e);
            }
        }
    }

    @Override
    public boolean migratePayWithdrawOrder(QueryTableDateDTO dto) {
        String uri = "/query/pay/base/query/order";
        String url = acmTransactionParams.getKaolakuaishouHost() + uri;
        JSONArray jsonArray = commonMigrateService.pullDataFromKS(url, dto.toJSON());
        if (jsonArray.size() == 0) {
            return false;
        }
        //parse（字符串转对象）的时候 设置下划线转驼峰
        ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

        List<PayWithdrawalPO> klksPayWithdrawalList = jsonArray.toJavaList(PayWithdrawalPO.class);

        updatePayWithdraw(klksPayWithdrawalList);
        return true;
    }

    /**
     * 更新交易
     *
     * @param klksPayTransactionPOList
     */
    private void updatePayTransaction(List<KlksPayTransactionPO> klksPayTransactionPOList) {

        for (KlksPayTransactionPO klksPayTransactionPO : klksPayTransactionPOList) {
            try {
                if (klksPayTransactionPO.getProductType().equals("06")){
                    KLog.warn("充值交易不迁移");
                    continue;
                }
                MigrateDTO migrateDTO = new MigrateDTO();
                migrateDTO.setData(klksPayTransactionPO.toJSON());

                //查询不到再插入新表,查交易通过
                int index = getTransTableIndex(getUserBaseId(userBaseExtMapper, klksPayTransactionPO.getUserId(), redis));

                PayTransaction oldPayTransaction = transactionPayTransactionMapper.getByOrderNo(index, klksPayTransactionPO.getOrderNo());
                if (Objects.isNull(oldPayTransaction)) {
                    migrateDTO.setOpt(MigrateDTO.OPT_INSERT);
                } else {
                    migrateDTO.setOpt(MigrateDTO.OPT_UPDATE);
                }
                payTransactionMigrateService.payTransaction(migrateDTO);

            } catch (Exception e) {
                KLog.error("迁移交易失败,交易记录:{}", klksPayTransactionPO, e);
            }
        }
    }

    /**
     * 更新交易index
     *
     * @param klksPayTransactionIndexList
     */
    private void updatePayTransactionIndex(List<KlksPayTransactionIndex> klksPayTransactionIndexList) {

        for (KlksPayTransactionIndex klksPayTransactionIndex : klksPayTransactionIndexList) {
            try {
                MigrateDTO migrateDTO = new MigrateDTO();
                migrateDTO.setData(klksPayTransactionIndex.toJSON());

                //查询不到再插入新表,查交易通过
                PayTransactionIndexExample oldIndexExample = new PayTransactionIndexExample();
                oldIndexExample.createCriteria()
                        .andOrderNoEqualTo(klksPayTransactionIndex.getOrderNo());
                List<PayTransactionIndex> oldIndexList = payTransactionIndexMapper.selectByExample(oldIndexExample);
                if (oldIndexList.isEmpty()) {
                    migrateDTO.setOpt(MigrateDTO.OPT_INSERT);
                } else {
                    migrateDTO.setOpt(MigrateDTO.OPT_UPDATE);
                }

                payTransactionMigrateService.payTransactionIndex(migrateDTO);

            } catch (Exception e) {
                KLog.error("迁移交易index失败,交易index记录:{}", klksPayTransactionIndex, e);
            }
        }
    }
}
